package com.zzyk.microCloud.controller;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageInfo;
import com.zzyk.main.configuration.exception.UserException;
import com.zzyk.main.controller.BaseController;
import com.zzyk.main.model.pojo.*;
import com.zzyk.main.model.vo.*;
import com.zzyk.main.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @author wss_PC
 * @DESCRIPTION 设备控制器
 * @create 2020-7-13
 */
@RestController
@CrossOrigin(allowCredentials = "true")
@RequestMapping("deviceData")
public class DeviceDataController extends BaseController {
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private DeviceUserateService deviceUserateService;
    @Autowired
    private DeviceElectricityDayService electricityDayService;
    @Autowired
    private DeviceParamService deviceParamService;
    @Resource
    private DeviceHarmonicRealService deviceHarmonicRealService;


    /**
     * 获取最新的谐波实时表
     */
    @GetMapping("/getDeviceHarmonicReal")
    public Message getDeviceHarmonicReal(Integer deviceId) {
        return Message.success().addData("data", deviceHarmonicRealService.getOne(new LambdaQueryWrapper<DeviceHarmonicReal>().eq(DeviceHarmonicReal::getDeviceId, deviceId).last("limit 1")));
    }

    /**
     * 获取今日用电量 柱状图
     *
     * @param day
     * @return
     */
    @GetMapping("/getEnergyUsedByDay")
    public List<Map<String, Object>> getEnergyUsedByDay(@RequestParam("day") String day) throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.getEnergyUsedByDay(day, sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取单日用电量 的峰谷平电量电费总电量电费
     *
     * @param day
     * @return
     * @throws UserException
     */
    @GetMapping("/getMorePowerConsumptionDay")
    public DeviceElectricityDay getMorePowerConsumptionDay(@RequestParam("day") String day) throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.getMorePowerConsumptionDay(day, sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取某年每个月的能耗
     *
     * @param year
     * @return
     * @throws UserException
     */
    @GetMapping("/getMorePowerConsumptionYear")
    public List<Map<String, Object>> getMorePowerConsumptionYear(String year) throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.getMorePowerConsumptionYear(year, sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取大屏首页用电量更多数据
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @GetMapping("/getMorePowerConsumption")
    public List<Map<String, Object>> getMorePowerConsumption(String startTime, String endTime) throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.getMorePowerConsumption(startTime, endTime, sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取年稼动率数据
     *
     * @param year
     * @return
     */
    @GetMapping("/getAnnualUtilizationRate")
    public Message getAnnualUtilizationRate(String year) throws UserException {
        SysUser sysUser = currentUser();
        return Message.success()
                .addData("data", deviceUserateService.getAnnualUtilizationRate(year, sysUser.getEnterprise(), sysUser.getDeviceList()))
                .addData("type", deviceService.countDeviceType(sysUser.getEnterprise(), sysUser.getDeviceList()));
    }

    /**
     * 导出生产详情
     *
     * @param dateTime
     * @param response
     * @throws UserException
     * @throws IOException
     */
    @GetMapping("/exportProductionDetails")
    public void exportProductionDetails(String dateTime, String token, HttpServletResponse response) throws UserException, IOException {
        SysUser sysUser = currentUserByToken(token);
        List<ProductionDetails> productionDetails = deviceService.getProductionDetails(dateTime, sysUser.getEnterprise(), sysUser.getDeviceList());
        ArrayList<Map<String, Object>> rows = new ArrayList();
        for (ProductionDetails productionDetail : productionDetails) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("设备名称", productionDetail.getName());
            map.put("设备类型", productionDetail.getDeviceType());
            map.put("设备编号", productionDetail.getSn());
            map.put("使用率", (double) Math.round(productionDetail.getUsageRate() * 100) / 100 + "%");
            map.put("稼动率", (double) Math.round(productionDetail.getUtilizationRate() * 100) / 100 + "%");
            map.put("累计生产时长", (double) Math.round(productionDetail.getProductionTime() * 100) / 100 + "h");
            map.put("用电总量", (double) Math.round(ObjectUtil.isNull(productionDetail.getPower()) ? 0 : productionDetail.getPower() * 100) / 100 + "kWh");
            map.put("告警次数", productionDetail.getCount() + "次");
            rows.add(map);
        }
        ExcelWriter writer = ExcelUtil.getWriter();
 /*       writer.addHeaderAlias("name", "设备名称");
        writer.addHeaderAlias("deviceType", "设备类型");
        writer.addHeaderAlias("sn", "设备编号");
        writer.addHeaderAlias("usageRate", "使用率");
        writer.addHeaderAlias("utilizationRate", "稼动率");
        writer.addHeaderAlias("productionTime", "累计生产时长");
        writer.addHeaderAlias("power", "用电总量");
        writer.addHeaderAlias("count", "告警次数");*/
        writer.merge(7, "设备生产详情");
        writer.write(rows, true);
        //out为OutputStream，需要写出到的目标流
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
//test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=" + new String(("设备生产详情 " + DateUtil.now() + ".xls").getBytes("GBK"), "ISO8859_1"));
        ServletOutputStream out = response.getOutputStream();

        writer.flush(out, true);
// 关闭writer，释放内存
        writer.close();
//此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

    /**
     * 获取 生产详情
     *
     * @return
     */
    @GetMapping("/ProductionDetails")
    public Message getProductionDetails(String dateTime) throws UserException {
        SysUser sysUser = currentUser();
        setPage();
        PageInfo<ProductionDetails> info = new PageInfo<>(deviceService.getProductionDetails(dateTime, sysUser.getEnterprise(), sysUser.getDeviceList()));
        return Message.success()
                .addData("data", info.getList())
                .addData("total", info.getTotal())
                .addData("pages", info.getPages());
    }

    /**
     * 获取设备类型稼动率
     *
     * @param dateTime
     * @return
     * @throws UserException
     */
    @GetMapping("/getDeviceTypeUtilizationRate")
    public List<KeyValueTwo> getDeviceTypeUtilizationRate(String dateTime) throws UserException {
        SysUser sysUser = currentUser();
        return deviceUserateService.getDeviceTypeUtilizationRate(dateTime, sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 设备每日平均生产时长走势
     *
     * @param dateTime
     * @return
     * @throws UserException
     */
    @GetMapping("/getAvgProductionTime")
    public List<CommonKeyValue> getAvgProductionTime(String dateTime) throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.getAvgProductionTime(dateTime, sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取生产报告下数据
     *
     * @param dateTime
     * @return
     * @throws UserException
     */
    @GetMapping("/productionReport")
    public List<DeviceUserate> getProductionReport(String dateTime) throws UserException {
        SysUser sysUser = currentUser();
        return deviceUserateService.getProductionReport(dateTime, sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 根据 clientID 获取设备参数
     * @param clientID
     * @return
     */
    @GetMapping("/getDeviceParamByClientID")
    public Message getDeviceParamByClientID(String clientID) {
        return Message.success().addData("data", deviceParamService.selectOneByDeviceId(clientID));
    }

    /**
     * 获取首页今日用能 根据设备类型分组
     * @return
     * @throws UserException
     */
    @GetMapping("/getTheEnergyYouUseToday")
    public List<KeyValue> getTheEnergyYouUseToday() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.getTheEnergyYouUseToday(sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 根据条件获取生产时长
     *
     * @param time 时间
     * @return
     */
    @GetMapping("/getProductionTimeHistogram")
    public List<KeyValue> getProductionTimeHistogram(String time) throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findProductionTimeHistogram(sysUser.getEnterprise(), time, sysUser.getDeviceList());
    }

    /**
     * 获取报告管理下的结论
     *
     * @param month
     * @return
     * @throws UserException
     */
    @GetMapping("/getReportConclusion")
    public Map<String, Object> getReportConclusion(String month) throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findReportConclusion(sysUser.getEnterprise(), month, sysUser.getDeviceList());
    }

    /**
     * 根据设备ID获取设备信息
     *
     * @param id
     * @return
     */
    @GetMapping("/getDeviceByDid")
    public Device getDeviceByDid(Integer id) {
        return deviceService.selectByPrimaryKey(id);
    }

    /**
     * 用能总览概括
     *
     * @param month
     * @return
     * @throws UserException
     */
    @GetMapping("/getOverviewOfEnergyUse")
    public HashMap<String, DeviceElectricityDay> getOverviewOfEnergyUse(String month) throws UserException {
        SysUser sysUser = currentUser();
        return electricityDayService.findOverviewOfEnergyUse(sysUser.getEnterprise(), month, sysUser.getDeviceList());
    }

    /**
     * 报告管理下用电质量参数考核分析 按月份查询
     *
     * @param month 月 默认为本月
     * @return
     */
    @GetMapping("/getElectricityParameters")
    public List<DeviceExtraData> getElectricityParameters(String month) throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findElectricityParameters(sysUser.getEnterprise(), month, sysUser.getDeviceList());
    }

    /**
     * 获取用电统计下所需数据
     *
     * @return
     */
    @GetMapping("/getElectricityStatistics")
    public CommonTimePojo getElectricityStatistics() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findElectricityStatistics(sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取企业所辖设备的有功和额定功率
     *
     * @return
     */
    @GetMapping("/getEnterprisePowerData")
    public List<KeyValue> getEnterprisePowerData() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findEnterprisePowerData(sysUser.getEnterprise());
    }

    /**
     * 获取更多生产时长 首页生产时长用
     */
    @GetMapping("/getMoreProductionTime")
    public EnterpriseProductionTime getMoreProductionTime() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findMoreProductionTime(sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取企业所辖所有设备的原始数据
     *
     * @return
     */
    @GetMapping("/getEnterpriseDeviceOriginData")
    public List<DeviceOriginData> getEnterpriseDeviceOriginData() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findEnterpriseDeviceOriginData(sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取企业用电分析下的健康指数评分
     *
     * @return
     */
    @GetMapping("/getEnterpriseHealth")
    public String getEnterpriseHealth() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findEnterpriseHealth(sysUser.getEnterprise());
    }

    /**
     * 获取企业所辖所有设备实时数据
     *
     * @return
     */
    @GetMapping("/getEnterpriseExtraData")
    public List<DeviceExtraData> getEnterpriseExtraData() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findEnterpriseExtraData(sysUser.getEnterprise(), sysUser.getDeviceList()
        );
    }

    /**
     * 获取登录用户所辖企业下所有设备功率总和
     *
     * @return
     */
    @GetMapping("/getEnterprisePower")
    public List<DateAndString> getEnterprisePower() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findEnterprisePower(sysUser.getEnterprise());
    }


    /**
     * 获取登录用户所辖企业下 所有设备使用率
     *
     * @return
     */
    @GetMapping("/getUsageRate")
    public List<Map<String, Object>> getUsageRate() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findUsageRate(sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取登录用户所辖企业下  稼动率
     *
     * @return
     */
    @GetMapping("/getUsageRateTwo")
    public Message getUsageRateTwo(String dateTime, String deviceName, Integer deviceType) throws UserException {
        SysUser sysUser = currentUser();
        setPage();
        PageInfo<KeyValueTwo> info = new PageInfo<>(deviceService.findUsageRateTwo(sysUser.getEnterprise(), dateTime, deviceName, deviceType, sysUser.getDeviceList()));
        return Message.success()
                .addData("data", info.getList())
                .addData("total", info.getTotal())
                .addData("pages", info.getPages());
    }

    /**
     * 获取本企业下所有设备今日用电量
     *
     * @return
     */
    @GetMapping("/getToDayPower")
    public List<DateAndString> getToDayPower() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findToDayPower(sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取生产时长区域下所需的数据
     *
     * @return
     * @throws UserException
     */
    @GetMapping("/getToDayProductionTime")
    public String getTotalProductionTime() throws UserException {
        SysUser sysUser = currentUser();
        return deviceService.findToDayProductionTime(sysUser.getEnterprise(), sysUser.getDeviceList());
    }

    /**
     * 获取设备使用率
     *
     * @return
     */
    @GetMapping("/getDeviceUserate")
    public List<DeviceUserate> getDeviceUserate(Integer id, String beginTime, String endTime, Integer type) {
        return deviceUserateService.findDeviceUserateBuDeviceId(id, beginTime, endTime, type);
    }


    /**
     * 根据企业ID获取生产设备
     *
     * @return
     */
    @GetMapping("/getDeviceByEId")
    public List<Device> getDeviceByEId() throws UserException {
        SysUser user = currentUser();
        return deviceService.findDeviceByEId(user.getEnterprise(), user.getDeviceList());
    }

    /**
     * 根据设备编号去查询 设备信息
     *
     * @param sn
     * @return 如果编号已经有了那么就返回true反之为false
     */
    @PostMapping("/verificationDeviceByNumber")
    public Map<String, Boolean> verificationDeviceByNumber(String sn, Integer type) {
        Map<String, Boolean> map = new HashMap<>(8);
        Device device = deviceService.selectDeviceByNumber(sn, type);
        if (ObjectUtil.isNull(device)) {
            map.put("valid", false);
            return map;
        }
        map.put("valid", true);
        return map;

    }

    /**
     * 统计生产设备设备全部数量和各个状态的数量
     *
     * @return
     */
    @GetMapping("getDeviceTotalByCompany")
    public Result getDeviceTotalByCompany() throws UserException {
        SysUser user = currentUser();
        try {
            return Result.ok(deviceService.getTotal(1, user.getEnterprise(), null, user.getDeviceList()));
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("查询失败");
        }
    }

    /**
     * 获取用电分析数据
     *
     * @param id
     * @return
     */
    @GetMapping("/getPowerConsumptionStatistics")
    public PowerConsumptionStatistics getPowerConsumptionStatistics(@RequestParam("id") Integer id) {
        return deviceService.findPowerConsumptionStatistics(id);
    }


    /**
     * 获取本月生产时长
     *
     * @param id
     * @return
     */
    @GetMapping("/getProductionTime")
    public List<DateAndString> getProductionTime(Integer id, String beginTime, String endTime, Integer type) {
        return deviceService.findProductionTime(id, beginTime, endTime, type);
    }

    /**
     * 根据时间范围查询功率
     *
     * @param id
     * @return
     */
    @GetMapping("/getRealPowerParam")
    public List<DateAndString> getRealPowerParam(Integer id, String beginTime, String endTime, Integer type) {
        return deviceService.findRealPowerParam(id, beginTime, endTime, type);
    }

    /**
     * 根据ID查询 实时功率 当天
     *
     * @param id
     * @return
     */
    @GetMapping("/getRealPower")
    public List<DateAndString> getRealPower(Integer id) {
        return deviceService.findRealPower(id);
    }

    /**
     * 根据用户传入的时间范围查询用电量、默认查询一个月。
     *
     * @param id
     * @param beginTime
     * @param endTime
     * @return
     */
    @GetMapping("/getTodayElectricityByParam")
    public List<DateAndString> getTodayElectricityByParam(Integer id, String beginTime, String endTime) {
        return deviceService.findTodayElectricityByParam(id, beginTime, endTime);
    }

    /**
     * 获取今天用电量
     *
     * @param id
     * @return
     */
    @GetMapping("/getTodayElectricity")
    public List<DateAndString> getTodayElectricity(Integer id) {
        return deviceService.findTodayElectricity(id);
    }

    /**
     * 用电分析更多图表
     *
     * @param id
     * @param beginTime
     * @param endTime
     * @return
     */
    @GetMapping("/getElectricityAnalysisDataByParam")
    public List<DeviceExtraData> getElectricityAnalysisDataByParam(Integer id, String beginTime, String endTime) {
        return deviceService.findElectricityAnalysisDataByParam(id, beginTime, endTime);
    }

    /**
     * 根据设备ID去查询设备实时数据
     *
     * @param id
     * @return
     */
    @GetMapping("/getElectricityAnalysisData")
    public DeviceExtraData getElectricityAnalysisData(Integer id) {
        return deviceService.findElectricityAnalysisData(id);
    }

    /**
     * 根据采集设备ID获取采集设备信息
     *
     * @return
     */
    @GetMapping("/getDeviceByGroup")
    public Device getDeviceByGroup(Integer group) {
        return deviceService.selectByPrimaryKey(group);
    }


    /**
     * 添加采集设备信息
     *
     * @param device
     * @return
     */
    @PostMapping("/saveCollectionEquipment")
    public Message saveCollectionEquipment(Device device) {
        try {
            device.setType(0);
            deviceService.insertSelective(device);
            return Message.success();
        } catch (Exception e) {
            e.printStackTrace();
            return Message.failed("保存失败");
        }
    }


    /**
     * 获取设备列表数据
     *
     * @param param
     * @return
     */
    @GetMapping("/getDeviceList")
    public Message getDeviceList(String param, Integer num, String sortParam, Integer deviceType, Integer pageIndex, Integer pageSize) throws UserException {
        SysUser user = currentUser();
        return deviceService.getDeviceListData(user.getEnterprise(), param, num, sortParam, pageIndex, pageSize, deviceType, user.getDeviceList());
    }

    /**
     * 根据ID查询设备信息
     *
     * @param id
     * @return
     */
    @GetMapping("/getProduceDeviceById")
    public Result getProduceDeviceById(Integer id) {
        try {
            return Result.ok(deviceService.selectDeviceById(id, 1));
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("查询失败");
        }
    }

    /**
     * 获取生产设备归管理设备列表
     *
     * @param param 快捷查询参数
     * @return
     */
    @GetMapping("getDeviceListByEnterprise")
    public Message getDeviceListByEnterprise(String param) throws UserException {
        SysUser user = currentUser();
        Integer[] deviceList = user.getDeviceList();
        setPage();
        PageInfo<Device> info = new PageInfo<>(deviceService.selectAllByParam(param, 1, user.getEnterprise(), null, deviceList,null));
        return Message.success()
                .addData("data", info.getList())
                .addData("total", info.getTotal())
                .addData("pages", info.getPages());
    }

    @GetMapping("/countDeviceStatusByParam")
    public List<KeyValue> getDeviceStatusByParam(String param, Integer deviceType) throws UserException {
        SysUser user = currentUser();
        return deviceService.findDeviceStatusByParam(user.getEnterprise(), param, deviceType, user.getDeviceList());
    }

    /**
     * 生成二维码
     *
     * @return 二维码本地地址
     */
    @GetMapping(value = "/getCloudQrCode", produces = MediaType.IMAGE_JPEG_VALUE)
    public byte[] getCloudQrCode(String value) {
        return QrCodeUtil.generatePng(value, 100, 100);
    }
}
